﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NetCommand
{
    public class NetCommandFactory
    {
        private static Dictionary<ushort, Type> commandTypeDictionary = new Dictionary<ushort, Type>();
        private static Dictionary<string, NetCommand> commandInstanceDictionary = new Dictionary<string, NetCommand>();

        /// <summary>
        /// 注册命令
        /// </summary>
        public static void RegistCommand()
        {
            createAndRegistCommand((ushort)CMD_ID_DEFINE.eID_D2S_IO_DEVICE, typeof(IO_Device));
        }

        private static void createAndRegistCommand(ushort id, Type cmdType)
        {
            commandTypeDictionary.Add(id, cmdType);
            NetCommand cmd = System.Activator.CreateInstance(cmdType) as NetCommand;
            commandInstanceDictionary.Add(cmdType.FullName, cmd); 
        }

        public static NetCommand GetCommand(Type type)
        {
            string typeName = type.FullName;
            if (commandInstanceDictionary.ContainsKey(typeName))
            {
                return commandInstanceDictionary[typeName];
            }
            NetCommand cmd = System.Activator.CreateInstance(type) as NetCommand;
            commandInstanceDictionary.Add(typeName, cmd);
            return cmd;
        }

        public static NetCommand GetCommand(ushort cmdId)
        {
            if (commandTypeDictionary.ContainsKey(cmdId) == false)
            {
                return null;
            }

            string typeName = commandTypeDictionary[cmdId].FullName;
            if (commandInstanceDictionary.ContainsKey(typeName))
            {
                return commandInstanceDictionary[typeName];
            }
            NetCommand cmd = System.Activator.CreateInstance(commandTypeDictionary[cmdId]) as NetCommand;
            commandInstanceDictionary.Add(typeName, cmd);
            return cmd;
        }

        public static T GetCommand<T>() where T : NetCommand
        {
            string typeName = typeof(T).FullName;
            if (commandInstanceDictionary.ContainsKey(typeName))
            {
                return commandInstanceDictionary[typeName] as T;
            }
            NetCommand cmd = System.Activator.CreateInstance<T>() as NetCommand;
            commandInstanceDictionary.Add(typeName, cmd);
            return cmd as T;
        }

        public static Type GetCommandType(ushort cmd_id)
        {
            if (commandTypeDictionary.ContainsKey(cmd_id))
            {
                return commandTypeDictionary[cmd_id];
            }
            return null;
        }

        public static object getFieldValueFromType(NetCommand cmd, int index)
        {
            foreach (var field in cmd.GetType().GetFields())
            {
                object[] fieldattrs = field.GetCustomAttributes(false);
              
                if (fieldattrs.Length > 0)
                {
                    SerializeFieldAttribute attr = (SerializeFieldAttribute)fieldattrs[0];
                    if(attr != null)
                    {
                        return field.GetValue(cmd);
                    }
                }
            }
            return null;
        }

    }
}
